nargs = 5;
for k = nargin:nargs-1
    switch k
        case 0
            xy = 10*rand(50,2);
        case 1
            n = size(xy,1);
            a = meshgrid(1:n);
            dmat = reshape(sqrt(sum((xy(a,:)-xy(a',:)).^2,2)),n,n);
        case 2
            n = size(xy,1);
            pop_size = n;
        case 3
            show_prog = 1;
        case 4
            show_res = 1;
        otherwise
    end
end

% Verify Inputs
n = size(xy,1);
[nr,nc] = size(dmat);
if n ~= nr || n ~= nc
    error('Invalid XY or DMAT inputs!')
end

% Sanity Checks
pop_size = max(1,min(n,round(real(pop_size(1)))));
show_prog = logical(show_prog(1));
show_res = logical(show_res(1));

% Initialize the Population
pop = zeros(pop_size,n);

% Run the NN
dist_history = zeros(1,pop_size);
if show_prog
    pfig = figure('Name','Current Solution','Numbertitle','off');
end
for p = 1:pop_size
    d = 0;
    this_rte = zeros(1,n);
    visited = zeros(1,n);
    I = p;
    visited(I) = 1;
    this_rte(1) = I;
    for k = 2:n
        dists = dmat(I,:);
        min_d = min(dists(~visited));
        J = find(dists == min_d);
        visited(J) = 1;
        this_rte(k) = J;
        d = d + dmat(I,J);
        I = J;
    end
    d = d + dmat(I,p);
    pop(p,:) = this_rte;
    dist_history(p) = d;

    if show_prog
        % Plot the Current Route
        figure(pfig);
        rte = [this_rte this_rte(1)];
        plot(xy(rte,1),xy(rte,2),'r.-');
        title(sprintf('Total Distance = %1.4f',dist_history(p)));
    end
end

% Find the Minimum Distance Route
[min_dist, index] = min(dist_history);
opt_rte = pop(index,:);

if show_res
    % Plots the NN Results
    figure('Name','TSPNN','Numbertitle','off');
    subplot(2,2,1);
    plot(xy(:,1),xy(:,2),'k.');
    title('City Locations');
    subplot(2,2,2);
    imagesc(dmat(opt_rte,opt_rte));
    title('Distance Matrix');
    subplot(2,2,3);
    rte = [opt_rte opt_rte(1)];
    plot(xy(rte,1),xy(rte,2),'r.-');
    title(sprintf('Total Distance = %1.4f',min_dist));
    subplot(2,2,4);
    plot(sort(dist_history),'b','LineWidth',2);
    title('Distances');
    set(gca,'XLim',[0 pop_size+1],'YLim',[0 1.1*max([1 dist_history])]);
end

% Return Outputs
if nargout
    varargout{1} = opt_rte;
    varargout{2} = min_dist;
end
